﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Content;

namespace GuildofHeroes
{

    class Player
    {
        public GuildofHeroes.AnimatedSprite m_Character = new GuildofHeroes.AnimatedSprite();
        public KeyboardState m_PreviousState;
        public PlayerState playerState = PlayerState.walking;
        
        //stats
        public int _BaseStrength = 10;
        //public int _BaseDexterity = 10;
        public int _BaseConstitution = 10;
        public int _BaseIntelligence = 10;
        public int _BaseWisdom = 10;
        public float _BasePlayerSpeed = 1.5f;

        public int _Level = 1;
        public int _Exp = 0;
        public int _NextLevelExp = 50;
        public int _BaseHealth = 0;
        public int _BaseMana = 0;
        public int _Gold = 0;
        public int m_Health = 0;
        public int m_Mana = 0;
        public int _BaseDamage = 0;
        public float _BaseHpRegen = 20;
        public int _BaseMPRegen = 1;
        
        public float _attackDelay = 0;
        

        public void WarriorLevel()
        {
            _Level++;
            _Exp = 0;
            _NextLevelExp += 50 * _Level / 2;
            _BaseHealth += 15 + (_Level + _BaseConstitution / 2);
            _BaseDamage += 1 + (_Level + _BaseStrength / 5);
            _BasePlayerSpeed += 0.003f;            
        }

        public void MageLevel()         
        {
            _Level++;
            _Exp = 0;
            _NextLevelExp += 50 * _Level / 2;
            _BaseHealth += 5 + (_Level + _BaseConstitution / 2);
            _BaseMana += 15 + (_Level + _BaseWisdom / 2);
            _BaseDamage += 1 + _Level + _BaseIntelligence / 5;
            _BasePlayerSpeed += 0.003f;          
        }

        public virtual void LevelUp()
        {
            _Level++;
            _Exp = 0;
            _NextLevelExp += 50 * _Level / 2;
            _BasePlayerSpeed += 0.003f;
            
        }

        public enum PlayerState
        {
            walking,
            jumping
        }

        public Player(Texture2D pTexture2D, int pPosX, int pPosY, int pNumFrames, int pFrameWidth, int pFrameHeight,
            int pHorizontalSpace, int pVerticalSpace, int pFramesPerSec, float pScale)
        {
            m_Character.LoadSprite(pTexture2D, pPosX, pPosY, pNumFrames, pFrameWidth, pFrameHeight, pHorizontalSpace, pVerticalSpace, pFramesPerSec, pScale);
            m_Health = _BaseHealth;
        }

        public int GetDamage()
        {
            if (_attackDelay < 0)
            {
                return _BaseDamage;
            }
            else
            {
                return 0;
            }

        }

        public void CheckMovement(KeyboardState pKeyboardState)
        {
            if (pKeyboardState.IsKeyDown(Keys.Right) && !DetectedScreenEdge("right"))
                m_Character.UpdatePos(_BasePlayerSpeed, 0f);
            if (pKeyboardState.IsKeyDown(Keys.Left) && !DetectedScreenEdge("left"))
                m_Character.UpdatePos(-_BasePlayerSpeed, 0f);
            if (pKeyboardState.IsKeyDown(Keys.Down) && !DetectedScreenEdge("bottom"))
                m_Character.UpdatePos(0.0f, _BasePlayerSpeed);
            if (pKeyboardState.IsKeyDown(Keys.Up) && !DetectedScreenEdge("top"))
                m_Character.UpdatePos(0.0f, -_BasePlayerSpeed);
            m_PreviousState = pKeyboardState;
        }

        public bool DetectedScreenEdge(string pEdge)
        {
            if (pEdge.ToLower() == "left" && m_Character.X - (m_Character.GetWidth() / 2) <= 0)
                return true;
            if (pEdge.ToLower() == "right" && m_Character.X + (m_Character.GetWidth() / 2) > Game1.ScreenWidth)
                return true;
            if (pEdge.ToLower() == "top" && m_Character.Y - (m_Character.GetHeight() / 2) <= 0)
                return true;
            if (pEdge.ToLower() == "bottom" && m_Character.Y + (m_Character.GetHeight() / 2) > Game1.ScreenHeight)
                return true;
            else
                return false;
        }

        public void Update(GameTime _gameTime, KeyboardState pKeyboardState)
        {
            if (_attackDelay < 0)
                _attackDelay = 0.1f;
            if (pKeyboardState.IsKeyDown(Keys.V))
                UpdateHealth(true, 10);
            if (pKeyboardState.IsKeyDown(Keys.B))
                UpdateHealth(false, 10);


            if (pKeyboardState.IsKeyDown(Keys.K))
                _Exp += 10;
            m_Character.Update(_gameTime);

            if (_Exp >= _NextLevelExp)
                LevelUp();

            _BaseHpRegen -= (float)_gameTime.ElapsedGameTime.TotalSeconds;

            if (m_Health < _BaseHealth && _BaseHpRegen <= 0)
            {                
                m_Health = m_Health + _Level +1;
                _BaseHpRegen = 20;
            }
            else if(m_Health >= _BaseHealth)
                m_Health = _BaseHealth;


            _attackDelay -= (float)_gameTime.ElapsedGameTime.TotalSeconds;
        }

        public void UpdateHealth(bool pDamage, int pAmount)
        {
            if (pDamage)
                m_Health -= pAmount;
            if (!pDamage)
                m_Health += pAmount;
            if (m_Health > _BaseHealth)
                m_Health = _BaseHealth;
            if (m_Health <= 0)
                m_Health = 0;

        }

        public bool isAlive()
        {
            if (m_Health <= 0)
                return true;

            return false;
        }

        public virtual void Draw(SpriteBatch _spriteBatch, SpriteFont _spriteFont)
        {
            m_Character.Draw(_spriteBatch);
        }

        public virtual void Draw(SpriteBatch _spriteBatch)
        {
            m_Character.Draw(_spriteBatch);
        }

        public void UpdatePos(float x, float y)
        {
            m_Character.X = x;
            m_Character.Y = y;
        }

        public void UpdateGold(int pGold)
        {
            _Gold += pGold;
        }

        public void UpdateExperience(int pExp)
        {
            _Exp += pExp;
        }

        public float GetPosX()
        {
            return m_Character.X;
        }

        public float GetPosY()
        {
            return m_Character.Y;
        }

        public int GetHealth()
        {
            return m_Health;
        }

        public int GetMana()
        {
            return m_Mana;
        }

        public int GetGold()
        {
            return _Gold;
        }

        public int GetDmgRating()
        {
            return _BaseDamage;
        }

        public int GetHeight()
        {
            return m_Character.GetHeight();
        }

        public int GetWidth()
        {
            return m_Character.GetWidth();
        }

        public Rectangle GetRectangle()
        {
            return m_Character.getRectangle();
        }

        public Vector2 Position()
        {
            return m_Character.getVectorPosition();
        }

        public int GetExp()
        {
            return _Exp;
        }

        public int GetLevel()
        {
            return _Level;
        }

        public int GetNextLevel()
        {
            return _NextLevelExp;
        }

    }

}